/*==========================================================================
 * 
 * CursorKeyListener.java
 * 
 * $Author: randallco $
 * $Revision: 1.5 $
 * $Date: 2007/05/18 03:05:49 $
 * $Name:  $
 * 
 * Created on 23-Nov-2003
 * Created by Marcel Palko alias Randallco (randallco@users.sourceforge.net)
 *==========================================================================*/
package net.sourceforge.ehep.events;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.custom.TableCursor;
import org.eclipse.swt.custom.ControlEditor;
import org.eclipse.jface.preference.PreferenceConverter;

import net.sourceforge.ehep.EhepPlugin;
import net.sourceforge.ehep.editors.*;
import net.sourceforge.ehep.core.*;
import net.sourceforge.ehep.gui.*;

/**
 * @author Marcel Palko alias Randallco
 * @author randallco@users.sourceforge.net
 */
public class CursorKeyListener extends KeyAdapter {

	private final HexEditor hexEditor;
	private final HexEditorControl hexEditorControl;
	private final TableCursor cursor;
	private final ControlEditor editor;
	private Font font;
	private Text text = null;
	private CellEditorKeyListener cellEditorKeyListener = null;
	
	private int eventColumnIndex;
	private HexTableItem eventItem;

	
	/**
	 * Creates a key listener for table cursor
	 * @param hexEditorControl
	 * @param hexEditor
	 * @param cursor
	 * @param editor
	 */
	public CursorKeyListener(final HexEditorControl hexEditorControl, final HexEditor hexEditor, final TableCursor cursor, final ControlEditor editor) {
		super();
		this.hexEditorControl = hexEditorControl;
		this.hexEditor = hexEditor;
		this.cursor = cursor;
		this.editor = editor;

		FontData fontData = PreferenceConverter.getFontData(EhepPlugin.getDefault().getPreferenceStore(), EHEP.PROPERTY_FONT);
		this.font = new Font(Display.getCurrent(), fontData);
	}

	/**
	 * Event handler for "key pressed" event
	 * @param e an event containing information about the key press
	 */
	public void keyPressed(KeyEvent e) {
		if (hexEditor.isReadOnly()) {
			//
			// File is read-only - do nothing
			//
			return;
		} // if
		
		if (e.keyCode == SWT.INSERT) {
			keyInsert();
			hexEditorControl.updateStatusPanel();
			return;
		} // if
		
		if (e.keyCode == SWT.DEL) {
			keyDelete();
			hexEditorControl.updateStatusPanel();
			return;
		} // if

		if (e.character != ',' && Character.digit(e.character, 16) == -1) {
			//
			// Invalid hex digit - ignore
			//
			return;
		} // if
		
		//
		// Valid hex digit
		//
		TableItem row = cursor.getRow();
		int column = cursor.getColumn();
		
		if (column == 0 || column > EHEP.TABLE_NUM_DATA_COLUMNS) {
			//
			// Wrong column - ignore
			//
			return;
		} // if
		
		if (row.getText(column).compareTo(EHEP.TABLE_EMPTY_CELL) == 0) {
			//
			// Cursor is out of file (over the cell without a content)
			//
			return;
		} // if
				
		//
		// Following operations are allowed only for columns 1...16 (actual hex view)
		//
		text = new Text(cursor, SWT.NONE);
		text.insert("" + e.character);
		text.setFont(font);
		text.setBackground(EhepPlugin.getColor(PreferenceConverter.getColor(EhepPlugin.getDefault().getPreferenceStore(), EHEP.PROPERTY_COLOR_BACKGROUND_EDITOR)));
		text.setForeground(EhepPlugin.getColor(PreferenceConverter.getColor(EhepPlugin.getDefault().getPreferenceStore(), EHEP.PROPERTY_COLOR_FOREGROUND_EDITOR)));
		text.setTextLimit(2);
		editor.setEditor(text);
		text.setFocus();

		//
		// Remember where the text editor was opened
		//
		HexTable table = hexEditorControl.getHexTable();
		int rowIndex = table.getSelectionIndex();
		eventColumnIndex = cursor.getColumn();
		eventItem = table.getItem(rowIndex);

		//
		// Add key listener to cell editor (Text component)
		//
		cellEditorKeyListener = new CellEditorKeyListener(hexEditorControl, hexEditor, cursor, editor, text);
		text.addKeyListener(cellEditorKeyListener);
	}

	private void keyInsert() {
		//
		// Insert new byte into the table
		//
		HexTable table = hexEditorControl.getHexTable();
		int rowIndex = table.getSelectionIndex();
		int columnIndex = cursor.getColumn();
		HexTableItem item = table.getItem(rowIndex);
			
		if (columnIndex == 0 || columnIndex == (EHEP.TABLE_NUM_COLUMNS-1) || item.getText(columnIndex).equals(EHEP.TABLE_EMPTY_CELL)) {
			//
			// Ignore - data insertion is not allowed
			//
			return;
		} // if
			
		//
		// Insert one table cell with default value 00h
		//
		hexEditorControl.insertData(1, 0, rowIndex, columnIndex-1, true);

		//
		// Set "dirty" flag
		//
		hexEditor.setDirty(true);
	}

	private void keyDelete() {
		//
		// Delete one byte from the table (if possible)
		//
		HexTable table = hexEditorControl.getHexTable();
		int rowIndex = table.getSelectionIndex();
		int columnIndex = cursor.getColumn();
		HexTableItem item = table.getItem(rowIndex);
			
		if (item == null || columnIndex == 0 || columnIndex == (EHEP.TABLE_NUM_COLUMNS-1) || item.getText(columnIndex).equals(EHEP.TABLE_EMPTY_CELL)) {
			//
			// Ignore - data deletion is not allowed
			//
			return;
		} // if
			
		//
		// Delete one table cell
		//
		// table.deleteData(1, rowIndex, columnIndex-1, true);
		hexEditorControl.delete(rowIndex, columnIndex-1, 1);

		//
		// Set "dirty" flag
		//
		hexEditor.setDirty(true);
	}

	public CellEditorKeyListener getCellEditorKeyListener() {
		return cellEditorKeyListener;
	}

	public Text getText() {
		return (text == null || text.isDisposed()) ? null : text;
	}

	public HexTableItem getEventItem() {
		return eventItem;
	}
	
	public int getEventColumn() {
		return eventColumnIndex;
	}
}
